# cluster
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
import seaborn as  sns
import warnings
warnings.filterwarnings('ignore')

class ClusterUtils(object):
    def __init__(self):
            self.df = pd.read_csv('./scenic_data.csv')
    def get_cluster(self):
            #提取特征并标准化
            features = self.df[['non_weekend_ratio', 'out_province_ratio', 'elderly_ratio']]
            scaler = StandardScaler()
            scaler_features = scaler.fit_transform(features)
            #使用K-means聚类
            kmeans = KMeans(n_clusters=4,random_state=42)
            self.df['cluster'] = kmeans.fit_predict(scaler_features)
            #查看聚类结果
            print(self.id[['tourist_agency_name','cluster']])
            #查看聚类中心（反标准化
            centers = scaler.inverse_transform(kmeans.cluster_centers_)
            print(pd.DataFrame(centers, columns=['non_weekend_ratio', 'out_province_ratio','elderly_ratio']))
            #保存结果
            self.df.to_csv('clustered_agencies.csv', index=False)
            #将聚类中心转换为DataFrame
            centers_df = pd.DataFrame(centers , columns=features.columns)
            centers_df['cluster'] = [f'Cluster{i}' for i in range(centers.shape[0]) ]
            #将宽边转换为长边
            centers_long = centers_df.melt(id_vars='cluster',var_name='feature', value_name='value')
            
            colors= ['#1f77b4','#ff7f0e','#2ca02c']
            plt.figure(figsize=(10,6))
            sns.barplot(x='feature', y='value', hue='cluster' , data=centers_long, palette=colors)
            plt.title('聚类中心特征对比')
            plt.ylabel('比例')
            plt.ylim(0,1)
            ply.legend(title='簇', bbox_to_anchor=(1.05, 1),loc ='upper left')
            
            #添加数值标签
            for p in plt.gca(),patches:
                height = p.get_height()
                plt.gca().text(p.get_x() + p.get_width() /2 , height +0.02,
                               f'{height: .2f}', ha='center')
            plt.tight_layout()
            plt.show()
if __name__ == '__main__':
    cu = ClusterUtils()
    cu.get_cluster()           